#!/usr/bin/perl -w

# Twatter version 0.3d
#
# an irc bot that 'twitters' everything said in an irc channel
#
# Author: Martin Pugh (s3krit) <pughparkour@gmail.com>
# Credit:
# O'Reilly's 'IRC Hackers' for the base irc bot: 
# 	http://oreilly.com/pub/h/1964
# Whoever it was on #/g/tv@rizon at 5am that suggested the damn idea!
#
# Copyright (C) 2009 Martin Pugh (s3krit) <pughparkour@gmail.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

use IO::Socket;
use Net::Twitter;
use threads;
use threads::shared;

# Set twitter info
my $username = "twitterusername";
my $password = "twitterpassword"; #better make sure to chmod 700 ;)
my $spacing = 60;	#how many seconds to wait inbetween sending twitters


# Set irc info
my $server = "irc.rizon.net";
my $nick = "Twatter";
my $login = "twatterbot";
my $channel = "#channelname";
#my $nickservpass = "pass"; # You only need this if you've registered the nick with nickserv

# And other misc variables
my $nexttime = time();
my @messages;
my $version = "0.3d";
my $lasttweet :shared;
my $nexttweet :shared;

$motd = "PRIVMSG $channel :$nick listening on $channel: http://www.twitter.com/$username (Twatter v$version)\r\n";

# Create new twitter object
my $nt = Net::Twitter->new(
	traits => [qw/API::REST/],
	username => $username,
	password => $password,
);


# Connect to the IRC server.
my $sock = new IO::Socket::INET(PeerAddr => $server,
                                PeerPort => 6667,
                                Proto => 'tcp') or
                                    die "Can't connect\n";

# Log on to the server.
print $sock "NICK $nick\r\n";
print $sock "USER $login 8 * :twatter v$version - a twitter robot for irc\r\n";

# Read lines from the server until it tells us we have connected.
while (my $input = <$sock>) {
	# Check the numerical responses from the server.
	if ($input =~ /004/) {
	# We are now logged in.
	last;
	}
	elsif ($input =~ /433/) {
        die "Nickname is already in use.";
	}
}

# Join the channel.

#Uncomment the following line if you wish for your bot to identify itself with nickserv
#print $sock "PRIVMSG nickserv :identify $nickservpass\r\n";
#Should probably join a channel, too...
print $sock "JOIN $channel\r\n";

# Following line prints a welcome message. It's not a necessity, but it is nice to inform people
print $sock $motd;

# Read lines from server
while (my $input = <$sock>) {
	chop $input;

	# Only print messages if not PING/PONGs
	if ($input =~ /^PING(.*)$/i) {
		print $sock "PONG $1\r\n";
	}
	else {
		print "$input\n";
	}
	
	# This is a bit messy. But it looks for messages to $channel and sends them to twitter
	if ($input =~ /^:\S+ PRIVMSG/i) {
		unless ($input =~ /^:\S+ PRIVMSG $nick/i || $input =~ /(http:|.4chan.|www.|:!twatter|:!lasttweet)/i){
			my $message = $input;
			$message =~ s/:(\S+)!\S+ PRIVMSG $channel :(\S+)/<$1> $2/;

			if ($nexttime < time()){
				push @messages, $message;
				$nexttweet = $messages[int(rand $#messages)];
				print $nexttweet;
				my $thr = threads->new(\&tweet);
				sub tweet {
				threads->detach();
				$nt->update($nexttweet);
				$lasttweet = $nexttweet;
				}
				$nexttime = time() + $spacing;
				@messages = ();
				print "@messages\n";
			}
			else{
				push @messages, $message;
			}
		}
	}

	if ($input =~ /^:(\S|\s)+PRIVMSG $channel :!twatter/i) {
		print $sock $motd;
	}
	if ($input =~ /^:(\S|\s)+PRIVMSG $channel :!lasttweet/i){
		print $sock "PRIVMSG $channel :Last tweet: $lasttweet\r\n";
	}

}
